package com.rabbitmq.comsumer.config;

import com.rabbitmq.comsumer.listener.CustomRabbitmqComsumerListener;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @作者: 林江
 * @创建时间: 2023/11/14
 * @功能:
 */
@Configuration
public class RabbitConfiguration {
    /**
     * 定义rabbitmq工厂
     *
     * @return
     */
    @Bean
    public CachingConnectionFactory cachingConnectionFactory() {
        CachingConnectionFactory factory = new CachingConnectionFactory();
        factory.setHost("192.168.32.128");
        factory.setPort(5672);
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setVirtualHost("/");
        return factory;
    }

    /**
     * 创建队列的实列
     *
     * @return
     */
    @Bean
    public RabbitAdmin rabbitAdmin() {
        RabbitAdmin admin = new RabbitAdmin(cachingConnectionFactory());
        Exchange ex = new FanoutExchange("sms");
        // 定义交换机
        admin.declareExchange(ex);
        // 定义队列
        Queue queue = queue();
        admin.declareQueue(queue);
        // 绑定队列
        Binding bind = new Binding(queue.getName(), Binding.DestinationType.QUEUE, ex.getName(), "123", null);
        admin.declareBinding(bind);
        return admin;
    }

    @Bean
    public Queue queue() {
        return new Queue("s1");
    }

    @Bean
    public Queue dlxQueue() {
        Map<String, Object> args = new HashMap();
        args.put("x-dead-letter-exchange", "some.exchange.name");
        return new Queue("dlx", false, true, false, args);
    }

    /**
     * 创建rabbitmq访问实列模板
     *
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory());
        // 配置重试
//        RetryTemplate retryTemplate = new RetryTemplate();
//        ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
//        backOffPolicy.setInitialInterval(2000); // 重试的间隔数：2s
//        retryTemplate.setBackOffPolicy(backOffPolicy);
//
//        rabbitTemplate.setRetryTemplate(retryTemplate);

        // 使用Jackson2JsonMessageConverter覆盖默认的SimpleMessageConverter消息转换器
        rabbitTemplate.setMessageConverter(jackson2JsonMessageConverter());

        return rabbitTemplate;
    }

    /**
     * 使用Jackson2JsonMessageConverter消息转换器的时候，进行的配置。
     *
     * @return
     */
    @Bean
    public MessageConverter jackson2JsonMessageConverter() {
        Jackson2JsonMessageConverter converter = new Jackson2JsonMessageConverter();
        // 2.4.7版本，可以设置对空的设置。
//        converter.setNullAsOptionalEmpty(true);
        // 监听器方法参数是接口形式
        converter.setUseProjectionForInterfaces(true);
//        DefaultClassMapper classMapper = new DefaultClassMapper();
//        classMapper.setTrustedPackages("*");
//        converter.setClassMapper(classMapper);

//        DefaultJackson2JavaTypeMapper javaTypeMapper = new DefaultJackson2JavaTypeMapper();
//        javaTypeMapper.setTrustedPackages("*"); // 配置受信任的包
//        converter.setJavaTypeMapper(javaTypeMapper);
        return converter;
    }


    /**
     * 配置监听器容器
     * 监听器容器维护消息监听的生命周期，通过它能够开启和关闭消息的监听。现有两种
     * 1.SimpleMessageListenerContainer
     * 2.DirectMessageListenerContainer
     */
//    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        // 设置连接工厂
        container.setConnectionFactory(cachingConnectionFactory());
        // 配置监听的队列
        container.setQueueNames("test02");
        // 设置监听队列的消息监听器
        container.setMessageListener(new CustomRabbitmqComsumerListener());
        // 配置消费者的优先级
        container.setConsumerArguments(Collections.<String, Object>singletonMap("x-priority", Integer.valueOf(10)));
        // 设置消息者的预取值,就是消费者从队列中一次只能获取一条消息。
        container.setPrefetchCount(1);
        // 设置消费者，消息确认机制，默认是auto，MANUAL表示手动返回ack
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);

        // 配置容器关闭的时候，自动的删除队列
        return container;
    }

    @Bean
    public RabbitListenerContainerFactory<SimpleMessageListenerContainer> prefetchRabbitListenerContainerFactory() {
        SimpleRabbitListenerContainerFactory container = new SimpleRabbitListenerContainerFactory();
        // 设置消息者的预取值,就是消费者从队列中一次只能获取一条消息。
        container.setPrefetchCount(1);
        // 设置消费者，消息确认机制，默认是auto，MANUAL表示手动返回ack
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        // 设置连接工厂
        container.setConnectionFactory(cachingConnectionFactory());
        return container;
    }
}
